package com.yanqu.road.server.gameplayer.module.retrieveReward;

import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.config.beauty.BeautyTrystResult;
import com.yanqu.road.entity.decoration.UserMammon;
import com.yanqu.road.entity.enums.*;
import com.yanqu.road.entity.estatewar.EstateBuildingInfo;
import com.yanqu.road.entity.estatewar.UserEstateFloor;
import com.yanqu.road.entity.estatewar.UserEstateWarData;
import com.yanqu.road.entity.log.LogRecoveryRewardResult;
import com.yanqu.road.entity.manor.FishPondData;
import com.yanqu.road.entity.player.PlayerState;
import com.yanqu.road.entity.player.UserHistoryAttribute;
import com.yanqu.road.entity.retrievereward.RecoveryRewardUserData;
import com.yanqu.road.entity.retrievereward.config.RecoveryRewardConfig;
import com.yanqu.road.entity.retrievereward.config.RecoveryRewardParameterConfig;
import com.yanqu.road.entity.servercenter.ServerGroup;
import com.yanqu.road.entity.servercenter.TitleInfo;
import com.yanqu.road.entity.tradewar.UserTradeWarBuilding;
import com.yanqu.road.logic.bussiness.activity.RecoveryRewardBusiness;
import com.yanqu.road.logic.config.ChannelConfig;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.pb.activity.RecoveryRewardProto;
import com.yanqu.road.pb.charitable.CharitableProto;
import com.yanqu.road.pb.clinic.ClinicProto;
import com.yanqu.road.pb.manor.ManorProto;
import com.yanqu.road.pb.wineshop.WineShopProto;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.gameplayer.module.charitable.CharitableDoTenTimeResult;
import com.yanqu.road.server.gameplayer.module.charitable.CharitableModule;
import com.yanqu.road.server.gameplayer.module.clinic.ClinicModule;
import com.yanqu.road.server.gameplayer.module.drugstore.DrugStoreModule;
import com.yanqu.road.server.gameplayer.module.grandson.GrandChildModule;
import com.yanqu.road.server.gameplayer.module.hunt.HuntModule;
import com.yanqu.road.server.gameplayer.module.manor.ManorFishPondModel;
import com.yanqu.road.server.gameplayer.module.manor.ManorModule;
import com.yanqu.road.server.gameplayer.module.player.*;
import com.yanqu.road.server.gameplayer.module.task.TaskModule;
import com.yanqu.road.server.gameplayer.module.travel.TravelModule;
import com.yanqu.road.server.gameplayer.module.union.cross.CrossUnionModule;
import com.yanqu.road.server.gameplayer.module.wineshop.WineShopModule;
import com.yanqu.road.server.manger.ConfigMgr;
import com.yanqu.road.server.manger.RecoveryReward.RecoveryRewardMgr;
import com.yanqu.road.server.manger.ServerGroupMgr;
import com.yanqu.road.server.manger.activity.ActivityMgr;
import com.yanqu.road.server.manger.config.*;
import com.yanqu.road.server.manger.log.AutoLogMgr;
import com.yanqu.road.server.manger.palace.PalaceActivity;
import com.yanqu.road.server.manger.palace.PalaceActivityMgr;
import com.yanqu.road.server.manger.player.EstateWarMgr;
import com.yanqu.road.server.pb.BeautyPb;
import com.yanqu.road.server.pb.CharitablePb;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Date;
import java.util.List;
import java.util.Map;

public class RecoveryRewardModule extends GeneralModule {

    private RecoveryRewardUserData userData;

    protected final Object lock = new Object();

    public RecoveryRewardModule(GamePlayer player) {
        super(player);
    }

    @Override
    public boolean loadData() {
        ActivityInfo activityInfo = RecoveryRewardMgr.getActivityInfo();
        if (activityInfo == null) {
            return true;
        }
        userData = RecoveryRewardBusiness.getRecoveryRewardUserData(getUserId());
        if (userData == null){
            initUserData();
        }
        return true;
    }

    @Override
    public boolean afterLoadData() {
        return false;
    }

    @Override
    public boolean saveData() {
        if (userData != null){
            if (userData.isInsertOption()){
                RecoveryRewardBusiness.addRecoveryRewardUserData(userData);
            }else if (userData.isUpdateOption()){
                RecoveryRewardBusiness.updateRecoveryRewardUserData(userData);
            }
        }

        return true;
    }

    @Override
    public void loginSendMsg() {
        super.loginSendMsg();
    }

    @Override
    public void afterLogin() {
        super.afterLogin();
    }

    public void resetOneDay(){
        if(player.getState() == PlayerState.ONLINE) {//玩家在线才执行
            if (userData != null){
                userData.setLastRecoveryTime(System.currentTimeMillis());
            }
        }
    }

    public void loginRetrieveReward() {
        // 系统未解锁
        if (!SystemOpenMgr.systemOpen(player, eSystemId.RecoveryReward.getValue())) {
            return;
        }

        // 没有活动
        ActivityInfo activityInfo = RecoveryRewardMgr.getActivityInfo();
        if (!ActivityMgr.activityInShowTime(activityInfo)) {
            return;
        }

        RecoveryRewardConfig config = RecoveryRewardMgr.getConfig();
        if (config == null){
            return;
        }

        if (player.getUserInfo().getTitleId() < config.getTitleLimit()){
            return;
        }

        if (userData == null) {
            initUserData();
        }

        if (ChannelConfig.RECOVERY_REWARD_SYSTEM_SWITCH != 1) {     //渠道开关
            return;
        }

        long now = System.currentTimeMillis();
        long lastRecoveryTime = 0;
        if (userData.getLastRecoveryTime() == 0) {
            lastRecoveryTime = player.getUserInfo().getLastLoginTime() * 1000;
        } else {
            lastRecoveryTime = userData.getLastRecoveryTime();
        }
        Date nowTime = new Date();
        //先设时间
        userData.setLastRecoveryTime(nowTime.getTime());
        //new一个builder
        RecoveryRewardProto.RecoveryRewardMsg.Builder builder = RecoveryRewardProto.RecoveryRewardMsg.newBuilder();
        //查看上次回收和这次登录间隔天数 calc2DateTDOADays()当天返回1 隔天返回2
        int totalOfflineDays = DateHelper.calc2DateTDOADays(new Date(lastRecoveryTime), new Date(now)) - 2;
        //如果是当天,隔天 直接返回
        if (totalOfflineDays < 1) {
            builder.setOfflineTime(totalOfflineDays);
            userData.setLastRecoveryTime(now);        //设置为现在
            player.sendPacket(ClientProtocol.U_RECOVERY_REWARD, builder);
            return;
        }
        int recoveryMaxConfigTime = RecoveryRewardMgr.getConfig().getRecoveryMaxTime();
        int maxRecoveryDay = recoveryMaxConfigTime < totalOfflineDays ? recoveryMaxConfigTime : totalOfflineDays;

        for (RecoveryRewardParameterConfig recoveryRewardParameterConfig : RecoveryRewardMgr.getConfig().getParameterConfigMap().values()) {
            int trueRecoverTime = calculateRecoveryTimeOrValue(recoveryRewardParameterConfig.getId(), maxRecoveryDay, recoveryRewardParameterConfig);
            if (trueRecoverTime <= 0) {
                continue;
            }
            doRecoveryReward(activityInfo.getActivityId(), recoveryRewardParameterConfig.getId(), trueRecoverTime, totalOfflineDays, builder, nowTime);
        }
        builder.setOfflineTime(maxRecoveryDay);
        player.sendPacket(ClientProtocol.U_RECOVERY_REWARD, builder);

    }

    private void doRecoveryReward(int activityId, int systemId, int trueRecoverTimes, int offlineDay, RecoveryRewardProto.RecoveryRewardMsg.Builder builder, Date nowTime) {

        RecoveryRewardParameterConfig recoveryRewardParameterConfig = RecoveryRewardMgr.getRecoveryRewardParameterConfig(systemId);
        if (recoveryRewardParameterConfig == null) {
            return;
        }
        if (recoveryRewardParameterConfig.getDiscountParameter() == 0) {
            return;
        }
        if (systemId == eRecoveryRewardType.BeautyTryst.getValue()) {
            BeautyTrystResult trystResult = player.getModule(BeautyModule.class).retrieveRewards(trueRecoverTimes);
            builder.setBeautyTrystRespMsg(BeautyPb.parseBeautyTrystRespMsg(trystResult));
            LogRecoveryRewardResult logRecoveryRewardResult = new LogRecoveryRewardResult(activityId, getUserId(), player.getUserInfo().getTitleId(), offlineDay, systemId, trueRecoverTimes, "", recoveryRewardParameterConfig.getDiscountParameter(), nowTime, "");
            AutoLogMgr.add(logRecoveryRewardResult);
            return;
        }
        if (systemId == eRecoveryRewardType.Child.getValue()) {
            int childPowerRecovery = player.getModule(ChildModule.class).recoveryRewardFindBackPower(trueRecoverTimes,recoveryRewardParameterConfig);
            builder.setChildRecoveryPower(childPowerRecovery);
            LogRecoveryRewardResult logRecoveryRewardResult = new LogRecoveryRewardResult(activityId, getUserId(), player.getUserInfo().getTitleId(), offlineDay, systemId, trueRecoverTimes, "totalPower = " + childPowerRecovery, recoveryRewardParameterConfig.getDiscountParameter(), nowTime, "");
            AutoLogMgr.add(logRecoveryRewardResult);
            return;
        }
        if (systemId == eRecoveryRewardType.Travel.getValue()) {
            //20240108增加参数
            RecoveryRewardProto.RecoverTravelGoRespMsg.Builder travelResult = TravelMgr.recoveryTravel(player, trueRecoverTimes,0);
            builder.setTravelResp(travelResult);
            LogRecoveryRewardResult logRecoveryRewardResult = new LogRecoveryRewardResult(activityId, getUserId(), player.getUserInfo().getTitleId(), offlineDay, systemId, trueRecoverTimes, "", recoveryRewardParameterConfig.getDiscountParameter(), nowTime, "");
            AutoLogMgr.add(logRecoveryRewardResult);
            return;
        }
        if (systemId == eRecoveryRewardType.Clinic.getValue()) {
            ClinicProto.GetClinicRewardListRespMsg.Builder clinicReward = player.getModule(ClinicModule.class).recoveryClinicReward(trueRecoverTimes);
            builder.setClinicResp(clinicReward);
            LogRecoveryRewardResult logRecoveryRewardResult = new LogRecoveryRewardResult(activityId, getUserId(), player.getUserInfo().getTitleId(), offlineDay, systemId, trueRecoverTimes, "reward:" + clinicReward.getReward() + "clinicScore:" + clinicReward.getClinicScore(), recoveryRewardParameterConfig.getDiscountParameter(), nowTime, "");
            AutoLogMgr.add(logRecoveryRewardResult);
            return;
        }
        if (systemId == eRecoveryRewardType.WineShop.getValue()) {
            WineShopProto.WineShopGetRewardRespMsg.Builder wineShopReward = player.getModule(WineShopModule.class).recoverReward(trueRecoverTimes);
            builder.setWineShopResp(wineShopReward);
            LogRecoveryRewardResult logRecoveryRewardResult = new LogRecoveryRewardResult(activityId, getUserId(), player.getUserInfo().getTitleId(), offlineDay, systemId, trueRecoverTimes, "", recoveryRewardParameterConfig.getDiscountParameter(), nowTime, "");
            AutoLogMgr.add(logRecoveryRewardResult);
            return;
        }
        if (systemId == eRecoveryRewardType.DrugStore.getValue()) {
            RecoveryRewardProto.RecoverDrugStoryMsg.Builder drugStoreReward = player.getModule(DrugStoreModule.class).recoverDrugStoreReward(trueRecoverTimes);
            if (drugStoreReward != null){
                builder.setDrugStoreResp(drugStoreReward);
                LogRecoveryRewardResult logRecoveryRewardResult = new LogRecoveryRewardResult(activityId, getUserId(), player.getUserInfo().getTitleId(), offlineDay, systemId, trueRecoverTimes, "", recoveryRewardParameterConfig.getDiscountParameter(), nowTime, "");
                AutoLogMgr.add(logRecoveryRewardResult);
            }
            return;
        }
        if (systemId == eRecoveryRewardType.GrandChild.getValue()) {
            RecoveryRewardProto.RecoverGrandSonRespMsg.Builder grandChildArchaeus = player.getModule(GrandChildModule.class).recoveryGrandChildArchaeus(trueRecoverTimes,recoveryRewardParameterConfig);
            builder.setGrandChildResp(grandChildArchaeus);
            StringBuffer rewardString = new StringBuffer("");
            for (RecoveryRewardProto.GrandSonArchaeusMsg singleMsg:grandChildArchaeus.getArchaeusMsgList()){
                rewardString.append(singleMsg.getGrandSonName()+"="+singleMsg.getRecoveryArchaeus());
            }
            LogRecoveryRewardResult logRecoveryRewardResult = new LogRecoveryRewardResult(activityId, getUserId(), player.getUserInfo().getTitleId(), offlineDay, systemId, trueRecoverTimes, rewardString.toString(), recoveryRewardParameterConfig.getDiscountParameter(), nowTime, "");
            AutoLogMgr.add(logRecoveryRewardResult);
            return;
        }
        if (systemId == eRecoveryRewardType.UnionConstruct.getValue()) {
            RecoveryRewardProto.UnionConstructResp.Builder unionConstruct = player.getModule(CrossUnionModule.class).recoveryUnionConstruct(trueRecoverTimes,recoveryRewardParameterConfig.getDiscountParameter());
            builder.setUnionConstructResp(unionConstruct);
            StringBuffer rewardString = new StringBuffer("");
            for (RecoveryRewardProto.UnionConstructData singleMsg:unionConstruct.getDataList()){
                rewardString.append(singleMsg.getType()+"="+singleMsg.getTimes());
            }
            LogRecoveryRewardResult logRecoveryRewardResult = new LogRecoveryRewardResult(activityId, getUserId(), player.getUserInfo().getTitleId(), offlineDay, systemId, trueRecoverTimes, rewardString.toString(), recoveryRewardParameterConfig.getDiscountParameter(), nowTime, "");
            AutoLogMgr.add(logRecoveryRewardResult);
            return;
        }
        if (systemId == eRecoveryRewardType.Charitable.getValue()) {
            CharitableDoTenTimeResult charitableDoTenTimeResult = player.getModule(CharitableModule.class).recoveryCharitable(trueRecoverTimes, recoveryRewardParameterConfig.getDiscountParameter(), builder);
            if (charitableDoTenTimeResult != null) {
                CharitableProto.CharitableTenDoResp.Builder charitableTenDoResp = CharitablePb.getCharitableTenDoResp(charitableDoTenTimeResult);
                builder.setCharitableResp(charitableTenDoResp);
                LogRecoveryRewardResult logRecoveryRewardResult = new LogRecoveryRewardResult(activityId, getUserId(), player.getUserInfo().getTitleId(), offlineDay, systemId, trueRecoverTimes, "", recoveryRewardParameterConfig.getDiscountParameter(), nowTime, "");
                AutoLogMgr.add(logRecoveryRewardResult);
            }
            return;
        }
        if (systemId == eRecoveryRewardType.Hunt.getValue()) {
            //来个折损比
            int discountParameter = recoveryRewardParameterConfig.getDiscountParameter();
            int finalScoreReward = player.getModule(HuntModule.class).recoveryHuntScore(trueRecoverTimes, discountParameter);
            if (finalScoreReward > 0) {
                builder.setHuntScoreAdd(GameConfig.GAME_MONEY_HUNT_SCORE + "=" + finalScoreReward);
                LogRecoveryRewardResult logRecoveryRewardResult = new LogRecoveryRewardResult(activityId, getUserId(), player.getUserInfo().getTitleId(), offlineDay, systemId, trueRecoverTimes, GameConfig.GAME_MONEY_HUNT_SCORE + "=" + finalScoreReward, recoveryRewardParameterConfig.getDiscountParameter(), nowTime, "");
                AutoLogMgr.add(logRecoveryRewardResult);
            }
            return;
        }
        if (systemId == eRecoveryRewardType.TitleReward.getValue()) {
            TitleInfo titleInfo = TitleMgr.getTitleInfo(player.getUserInfo().getTitleId());
            int dailyGetIngots = titleInfo.getDailyGetIngots();
            int discountParameter = recoveryRewardParameterConfig.getDiscountParameter();

            int finalIngots = dailyGetIngots * discountParameter * trueRecoverTimes / 1000;
            Property property = new Property(GameConfig.GAME_MONEY_INGOTS, BigInteger.valueOf(finalIngots));
            player.getModule(CurrencyModule.class).addCurrency(property,
                    eLogMoneyType.RecoveryReward, eLogMoneyType.RecoveryTitleIngotsRecovery);
            builder.setTitleIngotsRecovery(PropertyHelper.parsePropertyToString(property));
            LogRecoveryRewardResult logRecoveryRewardResult = new LogRecoveryRewardResult(activityId, getUserId(), player.getUserInfo().getTitleId(), offlineDay, systemId, trueRecoverTimes,PropertyHelper.parsePropertyToString(property) , recoveryRewardParameterConfig.getDiscountParameter(), nowTime, "");
            AutoLogMgr.add(logRecoveryRewardResult);
            return;
        }
        if (systemId == eRecoveryRewardType.DailyTaskReward.getValue()) {
            int discountParameter = recoveryRewardParameterConfig.getDiscountParameter();
            Property reward = player.getModule(TaskModule.class).recoveryDailyTaskReward(trueRecoverTimes, discountParameter);
            builder.setDailyTaskReward(PropertyHelper.parsePropertyToString(reward));
            LogRecoveryRewardResult logRecoveryRewardResult = new LogRecoveryRewardResult(activityId, getUserId(), player.getUserInfo().getTitleId(), offlineDay, systemId, trueRecoverTimes,PropertyHelper.parsePropertyToString(reward) , recoveryRewardParameterConfig.getDiscountParameter(), nowTime, "");
            AutoLogMgr.add(logRecoveryRewardResult);
            return;
        }
        if (systemId == eRecoveryRewardType.MammonReward.getValue()) {
            int oneDayIngots = ConfigMgr.getLeastRewardMammonSkill().getAddIngots();
            int discountParameter = recoveryRewardParameterConfig.getDiscountParameter();
            int totalRecovery = oneDayIngots * trueRecoverTimes * discountParameter / 1000;
            Property reward = PropertyHelper.parseStringToProperty(GameConfig.GAME_MONEY_INGOTS + "=" + totalRecovery);
            player.getModule(CurrencyModule.class).addCurrency(reward, eLogMoneyType.RecoveryReward, eLogMoneyType.RecoveryMammonWorshipIngots);
            builder.setMammonWorshipReward(PropertyHelper.parsePropertyToString(reward));
            LogRecoveryRewardResult logRecoveryRewardResult = new LogRecoveryRewardResult(activityId, getUserId(), player.getUserInfo().getTitleId(), offlineDay, systemId, trueRecoverTimes,PropertyHelper.parsePropertyToString(reward) , recoveryRewardParameterConfig.getDiscountParameter(), nowTime, "");
            AutoLogMgr.add(logRecoveryRewardResult);
            return;
        }
        if (systemId == eRecoveryRewardType.RankWorship.getValue()) {
            int leastWorshipRankReward = ConfigMgr.getLeastWorshipRankReward();
            ServerGroup groupByServerId = ServerGroupMgr.getServerGroupByServerId(GameServer.getInstance().getServerId());
            int discountParameter = recoveryRewardParameterConfig.getDiscountParameter();
            if (groupByServerId != null && groupByServerId.isCrossRank()) {
                leastWorshipRankReward = leastWorshipRankReward * 8;
            } else {
                leastWorshipRankReward = leastWorshipRankReward * 4;
            }
            leastWorshipRankReward = leastWorshipRankReward * trueRecoverTimes * discountParameter / 1000;
            Property reward = PropertyHelper.parseStringToProperty(GameConfig.GAME_MONEY_INGOTS + "=" + leastWorshipRankReward);
            player.getModule(CurrencyModule.class).addCurrency(reward, eLogMoneyType.RecoveryReward, eLogMoneyType.RecoveryRankWorshipIngots);
            builder.setRankWorship(PropertyHelper.parsePropertyToString(reward));
            LogRecoveryRewardResult logRecoveryRewardResult = new LogRecoveryRewardResult(activityId, getUserId(), player.getUserInfo().getTitleId(), offlineDay, systemId, trueRecoverTimes,PropertyHelper.parsePropertyToString(reward) , recoveryRewardParameterConfig.getDiscountParameter(), nowTime, "");
            AutoLogMgr.add(logRecoveryRewardResult);
            return;
        }
        if (systemId == eRecoveryRewardType.BuildingSliver.getValue()) {
            int discountParameter = recoveryRewardParameterConfig.getDiscountParameter();
            UserHistoryAttribute userHistoryAttribute = player.getModule(PlayerModule.class).getUserHistoryAttribute();
            BigInteger earnSpeed = userHistoryAttribute.getEarnSpeed();
            BigInteger totalSecond = BigInteger.valueOf((DateHelper.DAY_SECONDS * trueRecoverTimes - 43200) * discountParameter / 1000);
            BigInteger totalSliver = earnSpeed.multiply(totalSecond);
            Property reward = new Property(GameConfig.GAME_MONEY_SILVER, totalSliver);
            player.getModule(CurrencyModule.class).addCurrency(reward, eLogMoneyType.RecoveryReward, eLogMoneyType.RecoveryBuildingSliver);
            builder.setBuildingSliver(PropertyHelper.parsePropertyToString(reward));
            LogRecoveryRewardResult logRecoveryRewardResult = new LogRecoveryRewardResult(activityId, getUserId(), player.getUserInfo().getTitleId(), offlineDay, systemId, trueRecoverTimes,PropertyHelper.parsePropertyToString(reward) , recoveryRewardParameterConfig.getDiscountParameter(), nowTime, "");
            AutoLogMgr.add(logRecoveryRewardResult);
            return;
        }
        if (systemId == eRecoveryRewardType.TradeWarSliver.getValue()) {
            int discountParameter = recoveryRewardParameterConfig.getDiscountParameter();
            BigInteger totalValue = player.getModule(TradeWarBuildingModule.class).getSliverRecoveryValue(discountParameter,trueRecoverTimes);
            Property reward = new Property(GameConfig.GAME_MONEY_SILVER, totalValue);
            player.getModule(CurrencyModule.class).addCurrency(reward, eLogMoneyType.RecoveryReward, eLogMoneyType.RecoveryTaxOfficeSliver);
            builder.setTaxOffice(PropertyHelper.parsePropertyToString(reward));
            LogRecoveryRewardResult logRecoveryRewardResult = new LogRecoveryRewardResult(activityId, getUserId(), player.getUserInfo().getTitleId(), offlineDay, systemId, trueRecoverTimes,PropertyHelper.parsePropertyToString(reward) , recoveryRewardParameterConfig.getDiscountParameter(), nowTime, "");
            AutoLogMgr.add(logRecoveryRewardResult);
            return;
        }
        if (systemId == eRecoveryRewardType.ManorFishPondEnergy.getValue()) {
            Property property = new Property(GameConfig.FISHPOND_FISHING_ITEM_ID, BigInteger.valueOf(trueRecoverTimes));
            player.getModule(CurrencyModule.class).addCurrency(property, eLogMoneyType.RecoveryReward, eLogMoneyType.RecoveryFishPondPower);
            builder.setFishPondPower(PropertyHelper.parsePropertyToString(property));
            LogRecoveryRewardResult logRecoveryRewardResult = new LogRecoveryRewardResult(activityId, getUserId(), player.getUserInfo().getTitleId(), offlineDay, systemId, trueRecoverTimes,PropertyHelper.parsePropertyToString(property) , recoveryRewardParameterConfig.getDiscountParameter(), nowTime, "");
            AutoLogMgr.add(logRecoveryRewardResult);
            return;
        }
        if (systemId == eRecoveryRewardType.ManorHarvest.getValue()) {
            int discountParameter = recoveryRewardParameterConfig.getDiscountParameter();
            ManorProto.ManorHarvestRespMsg.Builder recoveryHarvest = player.getModule(ManorModule.class).recoveryHarvest(trueRecoverTimes, discountParameter);
            if (recoveryHarvest.getRet() == 0) {
                builder.setRecoveryHarvest(recoveryHarvest.getReward());
            }
            LogRecoveryRewardResult logRecoveryRewardResult = new LogRecoveryRewardResult(activityId, getUserId(), player.getUserInfo().getTitleId(), offlineDay, systemId, trueRecoverTimes,recoveryHarvest.getReward(), recoveryRewardParameterConfig.getDiscountParameter(), nowTime, "");
            AutoLogMgr.add(logRecoveryRewardResult);
            return;
        }

        if (systemId == eRecoveryRewardType.EstateWarWorship.getValue()) {
            int discountParameter = recoveryRewardParameterConfig.getDiscountParameter();
            PalaceActivity palaceActivity = PalaceActivityMgr.getInTimePalaceActivity();
            if (null != palaceActivity) {
                long beginShowTime = ActivityMgr.getOpenActivityInfo(palaceActivity.getPalaceActivityId()).getBeginShowTime();
                int hasOpenAllDay = DateHelper.calc2DateTDOADays(new Date(beginShowTime), new Date()) - 1;
                if (hasOpenAllDay != 0) {
                    int palaceTime = 0;
                    if (trueRecoverTimes > hasOpenAllDay) {
                        palaceTime = hasOpenAllDay;
                    } else {
                        palaceTime = trueRecoverTimes;
                    }
                    int rewardOneDay = palaceActivity.getPALACE_WORSHIP_REWARD_PARAM_LIST().get(0);
                    int allReward = rewardOneDay * palaceTime * discountParameter / 1000;
                    Property reward = new Property(palaceActivity.getPALACE_DAILY_REWARD_ITEM_ID(), BigInteger.valueOf(allReward));
                    player.getModule(CurrencyModule.class).addCurrency(reward, eLogMoneyType.RecoveryReward, eLogMoneyType.RecoveryEstateWarWorship);
                    builder.setPalaceReward(PropertyHelper.parsePropertyToString(reward));
                }
            }
            UserEstateWarData userEstateWarData = player.getModule(EstateWarModule.class).getUserEstateWarData();
            if (null == userEstateWarData) {
                return;
            }
            Property estateReward = new Property();
            for (EstateBuildingInfo buildingInfo : EstateWarConfigMgr.getEstateBuildingInfoMap().values()) {
                if (EstateWarConfigMgr.getEstateBuildingCanWorship(buildingInfo.getType())) {
                    List<UserEstateFloor> userEstateFloorList = EstateWarMgr.getEstateWarRankFloorList(buildingInfo.getType());
                    if(null == userEstateFloorList || userEstateFloorList.size() <= 0) {
                       continue;
                    }

                    if(!EstateWarConfigMgr.getEstateBuildingCanWorship(buildingInfo.getType())){
                       continue;
                    }
                    estateReward.addProperty(EstateWarConfigMgr.getWorshipReward(userEstateWarData));
                }
            }
            if (estateReward.isNothing()){
                builder.setEstateWarReward("");
                return;
            }
            int addition = trueRecoverTimes * discountParameter / 1000;
            estateReward.goodCountMultiNum(addition);
            player.getModule(CurrencyModule.class).addCurrency(estateReward, eLogMoneyType.RecoveryReward, eLogMoneyType.RecoveryEstateWarWorship);
            builder.setEstateWarReward(PropertyHelper.parsePropertyToString(estateReward));

            LogRecoveryRewardResult logRecoveryRewardResult = new LogRecoveryRewardResult(activityId, getUserId(), player.getUserInfo().getTitleId(), offlineDay, systemId, trueRecoverTimes,PropertyHelper.parsePropertyToString(estateReward), recoveryRewardParameterConfig.getDiscountParameter(), nowTime, "");
            AutoLogMgr.add(logRecoveryRewardResult);

            return;
        }

        if (systemId == eRecoveryRewardType.HouseBar.getValue()) {
            int discountParameter = recoveryRewardParameterConfig.getDiscountParameter();
            Property property = player.getModule(HouseModule.class).recoveryRecallPatrons(trueRecoverTimes, discountParameter);
            RecoveryRewardProto.RecoveryHouseRewardMsg.Builder houseBuilder = RecoveryRewardProto.RecoveryHouseRewardMsg.newBuilder();
            Map<Integer, BigInteger> propertyGoods = property.getGoods();
            if (propertyGoods.containsKey(GameConfig.GAME_ITEM_HOUSE_BANK_LUCK_ID)) {
                houseBuilder.setLuck(propertyGoods.get(GameConfig.GAME_ITEM_HOUSE_BANK_LUCK_ID).longValue() + "");
            }
            if (propertyGoods.containsKey(GameConfig.GAME_ITEM_CREDIT)) {
                houseBuilder.setCredit(propertyGoods.get(GameConfig.GAME_ITEM_CREDIT).intValue() + "");
            }
            builder.setHouseReward(houseBuilder);

            LogRecoveryRewardResult logRecoveryRewardResult = new LogRecoveryRewardResult(activityId, getUserId(), player.getUserInfo().getTitleId(), offlineDay, systemId, trueRecoverTimes,PropertyHelper.parsePropertyToString(property), recoveryRewardParameterConfig.getDiscountParameter(), nowTime, "");
            AutoLogMgr.add(logRecoveryRewardResult);

            return;
        }


    }
    //计算几天的找回
    private int calculateRecoveryTimeOrValue(int systemId, int days, RecoveryRewardParameterConfig recoveryRewardParameterConfig) {

        int shouldRecoveryTimes = days;

        if (systemId == eRecoveryRewardType.BeautyTryst.getValue()) {
            if (!SystemOpenMgr.systemOpen(player, eSystemId.Beauty.getValue())) {
                return 0;
            }
            int recoveryNeedTime = TitleMgr.getTitleInfo(player.getTitleId()).getBeautyEnergyRestoreTimeLower();
            if (0 == recoveryNeedTime) {
                recoveryNeedTime = GameConfig.BEAUTY_RESTORE_ENERGY_TIME;
            }
            TitleInfo titleInfo = TitleMgr.getTitleInfo(player.getTitleId());
            int maxEnergy = titleInfo.getBeautyAddEnergy();
            if (0 == maxEnergy) {
                maxEnergy = GameConfig.BEAUTY_MAX_ENERGY_VALUE;
            }
            int lastSaveTimePower = player.getModule(BeautyModule.class).getLastSaveTimePower();
            if (lastSaveTimePower < 0){
                log.info("玩家{}登录时未赋值给最后保存时刻美女体力导致未找回,原应找回次数{}",getUserId(),shouldRecoveryTimes);
                return 0;
            }

            shouldRecoveryTimes = calculateShouldRetrieveTimesByOneDayRecovery(maxEnergy, recoveryNeedTime, recoveryRewardParameterConfig.getDiscountParameter(),lastSaveTimePower,days) ;
            return shouldRecoveryTimes;
        }

        if (systemId == eRecoveryRewardType.Child.getValue()) {
            if (!SystemOpenMgr.systemOpen(player, eSystemId.Child.getValue())) {
                return 0;
            }

            return shouldRecoveryTimes;
        }

        if (systemId == eRecoveryRewardType.Travel.getValue()) {
            if (!SystemOpenMgr.systemOpen(player, eSystemId.Travel.getValue())) {
                return 0;
            }
            int recoveryNeedTime = GameConfig.TRAVEL_POWER_RESTORE_TIME;
            int maxPower = TravelMgr.getMaxTravelPower(player.getTitleId());
            int lastSaveTimePower = player.getModule(TravelModule.class).getLastSaveTimePower();
            if (lastSaveTimePower < 0){
                log.info("玩家{}登录时未赋值给最后保存时刻游历体力导致未找回,原应找回次数{}",getUserId(),shouldRecoveryTimes);
                return 0;
            }
            shouldRecoveryTimes = calculateShouldRetrieveTimesByOneDayRecovery(maxPower, recoveryNeedTime, recoveryRewardParameterConfig.getDiscountParameter(),lastSaveTimePower,days);
            return shouldRecoveryTimes;
        }

        if (systemId == eRecoveryRewardType.Clinic.getValue()) {
            if (!SystemOpenMgr.systemOpen(player, eSystemId.Clinic.getValue())) {
                return 0;
            }
            int recoveryNeedTime = GameConfig.CLINIC_PATIENT_RECOVERY_DURATION;
            ClinicModule clinicModule = player.getModule(ClinicModule.class);
            int maxPower = clinicModule.getMaxPower();
            int lastSaveTimePower =clinicModule.getLastSaveTimePatient();
            if (lastSaveTimePower < 0){
                log.info("玩家{}登录时未赋值给最后保存时刻医馆病人个数导致未找回,原应找回次数{}",getUserId(),shouldRecoveryTimes);
                return 0;
            }
            shouldRecoveryTimes = calculateShouldRetrieveTimesByOneDayRecovery(maxPower, recoveryNeedTime, recoveryRewardParameterConfig.getDiscountParameter(),lastSaveTimePower,days);
            return shouldRecoveryTimes;
        }

        if (systemId == eRecoveryRewardType.WineShop.getValue()) {
            if (!SystemOpenMgr.systemOpen(player, eSystemId.WineShop.getValue())) {
                return 0;
            }
            int lastSaveTimePower = player.getModule(WineShopModule.class).getLastSaveTimePower();
            if (lastSaveTimePower < 0){
                log.info("玩家{}登录时未赋值给最后保存时刻酒肆个数导致未找回,原应找回次数{}",getUserId(),shouldRecoveryTimes);
                return 0;
            }
            int recoveryNeedTime = GameConfig.WINESHOP_ENERGY_RECOVERY_TIME;
            shouldRecoveryTimes = calculateShouldRetrieveTimesByOneDayRecovery(GameConfig.WINESHOP_ENERGY_LIMIT, recoveryNeedTime, recoveryRewardParameterConfig.getDiscountParameter(),lastSaveTimePower,days);
            return shouldRecoveryTimes;
        }

        if (systemId == eRecoveryRewardType.DrugStore.getValue()) {
            if (!SystemOpenMgr.systemOpen(player, eSystemId.DrugStore.getValue())) {
                return 0;
            }
            int lastSaveTimePower = player.getModule(DrugStoreModule.class).getLastSaveTimePower();
            if (lastSaveTimePower < 0){
                log.info("玩家{}登录时未赋值给最后保存时刻药铺个数导致未找回,原应找回次数{}",getUserId(),shouldRecoveryTimes);
                return 0;
            }
            int recoveryNeedTime = GameConfig.DRUGSTORE_POWER_CD / GameConfig.DRUGSTORE_POWER_RENUM;
            shouldRecoveryTimes = calculateShouldRetrieveTimesByOneDayRecovery(GameConfig.DRUGSTORE_POWER_MAX, recoveryNeedTime, recoveryRewardParameterConfig.getDiscountParameter(),lastSaveTimePower,days);
            return shouldRecoveryTimes;
        }

        if (systemId == eRecoveryRewardType.GrandChild.getValue()) {
            if (!SystemOpenMgr.systemOpen(player, eSystemId.GrandChild.getValue())) {
                return 0;
            }
            return shouldRecoveryTimes;
        }

        if (systemId == eRecoveryRewardType.UnionConstruct.getValue()) {
            if (!SystemOpenMgr.systemOpen(player, eSystemId.Union.getValue())) {
                return 0;
            }
            if (StringUtils.isNullOrEmpty(player.getUserInfo().getUnionUid())){
                return 0;
            }
            shouldRecoveryTimes = days;             //一天一次 普通建设
            return shouldRecoveryTimes;
        }

        if (systemId == eRecoveryRewardType.Charitable.getValue()) {
            if (!SystemOpenMgr.systemOpen(player, eSystemId.Charitable.getValue())) {
                return 0;
            }

            shouldRecoveryTimes = days;
            return shouldRecoveryTimes;
        }

        if (systemId == eRecoveryRewardType.Hunt.getValue()) {
            if (!SystemOpenMgr.systemOpen(player, eSystemId.Hunt.getValue())) {
                return 0;
            }
            if(!HuntConfigMgr.isHuntSystemOpenTime()){
                return 0;
            }
            shouldRecoveryTimes = days;
            return shouldRecoveryTimes;
        }

        if (systemId == eRecoveryRewardType.TitleReward.getValue()) { //身份 先占位
            shouldRecoveryTimes = days;
            return shouldRecoveryTimes;
        }
        if (systemId == eRecoveryRewardType.MammonReward.getValue()) { //身份 先占位
            UserMammon userMammon = player.getModule(MammonModule.class).getUserMammon();
            if (null == userMammon) {
                return 0;
            }
            shouldRecoveryTimes = days;
            return shouldRecoveryTimes;
        }


        if (systemId == eRecoveryRewardType.DailyTaskReward.getValue()) {
            shouldRecoveryTimes = days;
            return shouldRecoveryTimes;
        }
        if (systemId == eRecoveryRewardType.TradeWarSliver.getValue()) {
            if (!SystemOpenMgr.systemOpen(player, eSystemId.TradeWar.getValue())) {
                return 0;
            }

            if (player.getModule(CardModule.class).isInCardTime(eCardType.YearCard.getValue())) {    //年卡不补！
                return 0;
            }
            TradeWarBuildingModule tradeWarBuildingModule = player.getModule(TradeWarBuildingModule.class);
            UserTradeWarBuilding userTradeWarBuilding = tradeWarBuildingModule.getUserTradeWarBuilding(eTradeWarBuildingType.TaxOffice.getValue());
            if (null == userTradeWarBuilding) {//商战建筑未解锁 按理说不可能 35级了都
                return 0;
            }
            return days;
        }
        if (systemId == eRecoveryRewardType.ManorFishPondEnergy.getValue()) {
            if (!SystemOpenMgr.systemOpen(player, eSystemId.ManorSystem.getValue())) {
                return 0;
            }
            if (!SystemOpenMgr.systemOpen(player, eSystemId.FishPond.getValue())) {     //里面有特殊判断
                return 0;
            }
            String[] config = GameConfig.FISHPOND_ENERGY_RECOVERY_PARAM.split(",");
            int maxNum = StringUtils.string2intSafe(config[2], 8);
            //恢复一点需要的时间 分钟
            int recoveryNeedTime = StringUtils.string2intSafe(config[1], 180);
            int recoverValuePerTimes = StringUtils.string2intSafe(config[0], 1);
            ManorFishPondModel manorFishPondModel = player.getModule(ManorModule.class).getManorFishPondModel();
            FishPondData fishPondData = manorFishPondModel.getFishPondData();
            if (fishPondData == null){
                return 0;
            }
            //上次领取的时间
            long recoveryTime = fishPondData.getRecoveryTime();
            //离线第二天零点
            long lastSaveRecord = DateHelper.getTodayZeroTimeStamp();
            //恢复满需要的时间
            long recoveryToMaxNeedTime = maxNum * recoveryNeedTime * DateHelper.MINUTE_MILLIONS;
            //恢复满到的时间
            long recoveryToMaxTime = recoveryTime + recoveryToMaxNeedTime;
            //总共恢复的时间
            long totolRecoveryTime = days * DateHelper.DAY_MILLIONS;
            //差值
            if (lastSaveRecord > recoveryToMaxTime){
                shouldRecoveryTimes = (int) (totolRecoveryTime / DateHelper.MINUTE_MILLIONS / recoveryNeedTime * recoverValuePerTimes);
            } else {
                //需要扣除的
                long needDeduction = recoveryToMaxTime - lastSaveRecord;
                shouldRecoveryTimes = (int) ((totolRecoveryTime - needDeduction)/DateHelper.MINUTE_MILLIONS / recoveryNeedTime * recoverValuePerTimes);
            }

            return shouldRecoveryTimes;
        }

        if (systemId == eRecoveryRewardType.ManorHarvest.getValue()) {
            if (!SystemOpenMgr.systemOpen(player, eSystemId.ManorSystem.getValue())) {
                return 0;
            }
            return days;
        }

        if (systemId == eRecoveryRewardType.EstateWarWorship.getValue()) {
            if (!SystemOpenMgr.systemOpen(player, eSystemId.EstateWar.getValue())) {
                return 0;
            }
            return days;
        }

        return shouldRecoveryTimes;

    }


    /**
     * 秒做单位 查看还能找回几次
     *
     * @param recoveryNeedTime
     * @param discountRatio
     * @return
     */

    public int calculateShouldRetrieveTimesByOneDayRecovery(int oneDayMax, int recoveryNeedTime, int discountRatio ,int lastSaveTimePower,int days) {
        int shouldRetrieveTimes = 0;
        int oneDayMaxRetrieveTimes = new Long(DateHelper.DAY_SECONDS / recoveryNeedTime).intValue();
        if (oneDayMaxRetrieveTimes > oneDayMax) {
            oneDayMaxRetrieveTimes = oneDayMax;
        }
        //先算每日找回次数*天数-恢复到上限的次数(小于0就不用找了)
        if (lastSaveTimePower > oneDayMax){
            shouldRetrieveTimes = oneDayMaxRetrieveTimes * days;
        }else {
            shouldRetrieveTimes = oneDayMaxRetrieveTimes * days - (oneDayMax - lastSaveTimePower);
        }
        if (shouldRetrieveTimes <= 0){
            return 0;
        }
        shouldRetrieveTimes = BigDecimal.valueOf(shouldRetrieveTimes).multiply(BigDecimal.valueOf(discountRatio).divide(BigDecimal.valueOf(1000),1,BigDecimal.ROUND_DOWN)).setScale(0,BigDecimal.ROUND_DOWN).intValue();
        if (shouldRetrieveTimes <= 0) {
            return 0;
        }
        return shouldRetrieveTimes;

    }

    public void initUserData() {

        // 没有活动
        ActivityInfo activityInfo = RecoveryRewardMgr.getActivityInfo();
        if (!ActivityMgr.activityInShowTime(activityInfo)) {
            return;
        }

        // 已经有数据了
        if (userData != null) {
            return;
        }
        RecoveryRewardUserData tmpData = new RecoveryRewardUserData();
        tmpData.setUserId(getUserId());
        tmpData.setLastRecoveryTime(0);
        tmpData.setInsertOption();
        userData = tmpData;

    }


}
